package qin.util;

import java.lang.reflect.Field;
import java.lang.reflect.Parameter;

import qin.annotation.Length;
import qin.annotation.NoEmpty;
import qin.annotation.Range;
import qin.annotation.Valid;

/**
 * 反射工具类
 * @author 小行星
 *
 */
public class ReflectionUtils {
	
	/**
	 * 传入一个浮点数，得到整数部分长度
	 * @param x
	 * @return
	 */
	public static int getDoubleLen(double x) {
		String s = String.valueOf(x);
		for(int i = 0; i < s.length(); i++) {
			if(s.charAt(i) == '.') return i;
		}
		return s.length();
	}
	/**
	 * 判断该对象或者接口是否标注 校验注解
	 * @param clazz
	 * @return
	 */
	public static boolean hasValid(Class<?> clazz) {
		if(clazz.isAnnotationPresent(Valid.class)) return true;
		
		for (Class<?> fa : clazz.getInterfaces()) {
			if(fa.isAnnotationPresent(Valid.class)) return true;
		}
		return false;
	}
	
	/**
	 * 检查要校验的对象
	 * @param parameter
	 * @param obj
	 * @return
	 */
	public static String toCheckObj(Parameter parameter, Object obj) {
		if(parameter.isAnnotationPresent(Valid.class))
			return toCheckComplexObj(parameter, obj);
		return toCheckSimpleObj(parameter, obj);
	}
	
	/**
	 * 检查要校验的基本对象
	 * @param parameter
	 */
	public static String toCheckSimpleObj(Parameter parameter, Object obj) {
		if(obj == null) {
			NoEmpty noEmpty = parameter.getAnnotation(NoEmpty.class);
			if(null != noEmpty) {
				return "警告！" + noEmpty.value() + "不能为空！";
			}

			return "";
		}
		
		Length length = parameter.getAnnotation(Length.class);
		if(length != null) {
			if(obj instanceof String) {
				String str = (String)obj;
				if(length.min() > str.length() || str.length() > length.max()) {
					return "字符串长度不合法！长度只允许在["+length.min()+","+length.max()+"]";
				}
			}else {
				System.out.println("非字符串不允许设置");
			}
		}
		Range range = parameter.getAnnotation(Range.class);
		if(range != null) {
			if(obj instanceof Double) {
				Double p = (Double)obj;
				int len = getDoubleLen(p);
				if(len > range.value()) {
					return "浮点数长度不允许超过" + range.value();
				}
			}else {
				System.out.println("非浮点数不允许");
			}
		}
		return "";
	}
	
	/**
	 * 检查要校验的基本对象
	 * @param parameter
	 */
	public static String toCheckSimpleObj(Field field, Object obj) {
		if(obj == null) {
			NoEmpty noEmpty = field.getAnnotation(NoEmpty.class);
			if(null != noEmpty) {
				return "警告！" + noEmpty.value() + "不能为空！";
			}

			return "";
		}
		
		Length length = field.getAnnotation(Length.class);
		if(length != null) {
			if(obj instanceof String) {
				String str = (String)obj;
				if(length.min() > str.length() || str.length() > length.max()) {
					return "字符串长度不合法！长度只允许在["+length.min()+","+length.max()+"]";
				}
			}else {
				System.out.println("非字符串不允许设置");
			}
		}
		Range range = field.getAnnotation(Range.class);
		if(range != null) {
			if(obj instanceof Double) {
				Double p = (Double)obj;
				int len = getDoubleLen(p);
				if(len > range.value()) {
					return "浮点数长度不允许超过" + range.value();
				}
			}else {
				System.out.println("非浮点数不允许");
			}
		}
		return "";
	}
	
	/**
	 * 检查要校验的复合对象
	 * @param parameter
	 * @param obj 保证不为空
	 * @return
	 */
	public static String toCheckComplexObj(Parameter parameter, Object obj) {
		if(obj == null) {
			NoEmpty noEmpty = parameter.getAnnotation(NoEmpty.class);
			if(null != noEmpty) {
				return "警告！" + noEmpty.value() + "不能为空！";
			}

			return "";
		}
		
		Class<?> clazz = obj.getClass();
		
		for (Field field : clazz.getDeclaredFields()) {
			field.setAccessible(true);
			try {
				Object p = field.get(obj);
				String res = toCheckSimpleObj(field, p);
				if(!res.isEmpty()) {
					return res;
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		
		return "";
	}
}
